<?php
/**
 *+------------------
 * madong
 *+------------------
 * Copyright (c) https://gitee.com/motion-code  All rights reserved.
 *+------------------
 * Author: Mr. April (405784684@qq.com)
 *+------------------
 * Official Website: http://www.madong.tech
 */

namespace madong\think\wf\services;

use madong\think\wf\basic\BaseService;
use madong\ingenious\enums\IsEnabledEnum;
use madong\ingenious\enums\ProcessConstEnum;
use madong\ingenious\interface\model\IProcessSurrogate;
use madong\ingenious\interface\services\IProcessSurrogateService;
use madong\ingenious\libs\utils\ArrayHelper;
use madong\ingenious\libs\utils\AssertHelper;
use madong\ingenious\libs\utils\DateTimeHelper;
use madong\ingenious\libs\utils\Pagination;
use madong\ingenious\libs\utils\PropertyCopier;
use madong\think\wf\dao\ProcessSurrogateDao;

class ProcessSurrogateService extends BaseService implements IProcessSurrogateService
{

    public function __construct()
    {
        $this->dao = new ProcessSurrogateDao();
    }

    public function created(object $param): ?IProcessSurrogate
    {
        unset($param->id);
        AssertHelper::notNull($param->start_time ?? '', '起始时间不能为空');
        AssertHelper::notNull($param->end_time ?? '', '结束时间不能为空');
        $param->start_time = DateTimeHelper::convertToTimestamp($param->start_time);
        $param->end_time   = DateTimeHelper::convertToTimestamp($param->end_time);
        return $this->dao->save((array)$param);
    }

    public function updated(object $param): bool
    {
        AssertHelper::notNull($param->id ?? '', '参数ID不能为空');
        AssertHelper::notNull($param->start_time ?? '', '起始时间不能为空');
        AssertHelper::notNull($param->end_time ?? '', '结束时间不能为空');
        $param->start_time = DateTimeHelper::convertToTimestamp($param->start_time);
        $param->end_time   = DateTimeHelper::convertToTimestamp($param->end_time);
        $model             = $this->dao->get($param->id);
        PropertyCopier::copyProperties($param, $model);
        return $model->save();
    }

    public function del(string|array|int $data): array
    {
        return $this->transaction(function () use ($data) {
            $data       = ArrayHelper::normalize($data);
            $deletedIds = [];
            foreach ($data as $id) {
                $item = $this->dao->get($id);
                if (!$item) {
                    continue; // 如果找不到项，跳过
                }
                $item->delete();//删除主表
                $primaryKey   = $item->getPk();
                $deletedIds[] = $item->{$primaryKey};
            }
            return $deletedIds;
        });
    }

    public function list(object $param): array
    {
        $where = ArrayHelper::paramsFilter($param, [
            ['name'],
            ['display_name'],
            ['operator', $param->{ProcessConstEnum::CREATE_USER->value} ?? ''],
            ['surrogate'],
            ['enabled'],
            ['process_define_id'],
        ]);
        [$page, $limit] = Pagination::getPageValue($param);
        [$items, $total] = $this->dao->getList($where, '*', $page, $limit, '', []);
        return compact('items', 'total');
    }

    public function findById(string|int $id): ?IProcessSurrogate
    {
        return $this->dao->get($id,['*'],['define']);
    }

    public function getSurrogate(string|int $operator, string|int $processName): ?string
    {
        $map1                 = [
            'operator'     => $operator,
            'process_name' => $processName,
            'enabled'      => IsEnabledEnum::YES->value,
        ];
        $processSurrogateList = $this->dao->selectList($map1, '*', 0, 0, 'create_time desc', [], true);
        if (empty($processSurrogateList)) {
            return null;
        }
        foreach ($processSurrogateList as $processSurrogate) {
            // 为空表示全部，优先级最高，直接返回
            if (empty($processSurrogate->getData('process_name'))) {
                // 开始时间判断
                if (!is_null($processSurrogate->getData('start_time')) && $processSurrogate->getData('start_time') > time()) {
                    continue;
                }
                // 结束时间判断
                if (!is_null($processSurrogate->getData('end_time')) && $processSurrogate->getData('end_time') < time()) {
                    continue;
                }
                return $processSurrogate->getData('surrogate');
            }
        }
        // 取满足条件的最新一条
        $filteredSurrogates = array_filter($processSurrogateList->all(), function ($processSurrogate) use ($processName) {
            // 只查询流程名称一样的
            if ($processSurrogate->getData('process_name') !== $processName) {
                return false;
            }
            // 开始时间判断
            if (!is_null($processSurrogate->getData('start_time')) && $processSurrogate->getData('start_time') > time()) {
                return false;
            }
            // 结束时间判断
            if (!is_null($processSurrogate->getData('end_time')) && $processSurrogate->getData('end_time') < time()) {
                return false;
            }
            return true;
        });
        if (!empty($filteredSurrogates)) {
            $filteredSurrogate = reset($filteredSurrogates); // 获取第一个满足条件的元素
            return $filteredSurrogate->getData('surrogate');
        }
        return null;
    }
}
